import { mapState, mapMutations } from 'vuex'
import { getResource } from '@/http'

export const originalThemeColor = '#409EFF'

const tintColor = (color, tint) => {
  let red = parseInt(color.slice(0, 2), 16)
  let green = parseInt(color.slice(2, 4), 16)
  let blue = parseInt(color.slice(4, 6), 16)

  if (tint === 0) {
    // when primary color is in its rgb space
    return [red, green, blue].join(',')
  } else {
    red += Math.round(tint * (255 - red))
    green += Math.round(tint * (255 - green))
    blue += Math.round(tint * (255 - blue))

    red = red.toString(16)
    green = green.toString(16)
    blue = blue.toString(16)

    return `#${red}${green}${blue}`
  }
}

const shadeColor = (color, shade) => {
  let red = parseInt(color.slice(0, 2), 16)
  let green = parseInt(color.slice(2, 4), 16)
  let blue = parseInt(color.slice(4, 6), 16)

  red = Math.round((1 - shade) * red)
  green = Math.round((1 - shade) * green)
  blue = Math.round((1 - shade) * blue)

  red = red.toString(16)
  green = green.toString(16)
  blue = blue.toString(16)

  return `#${red}${green}${blue}`
}

const getThemeCluster = themeColor => {
  const clusters = [themeColor]
  for (let i = 0; i <= 9; i++) {
    clusters.push(tintColor(themeColor, Number((i / 10).toFixed(2))))
  }
  clusters.push(shadeColor(themeColor, 0.1))
  return clusters
}

const replaceColor = (cssText, oldCluster, newCluster) => {
  let newCssText = cssText
  oldCluster.forEach((color, index) => {
    newCssText = newCssText.replace(new RegExp(color, 'ig'), newCluster[index])
  })
  return newCssText
}

export const updateTheme = async (val, oldVal) => {
  if (typeof val !== 'string') {
    return
  }
  const themeStylePrefix = 'theme-style-'

  const newThemeCluster = getThemeCluster(val.replace('#', ''))

  const originalThemeCluster = getThemeCluster(originalThemeColor.replace('#', ''))

  const links = [].slice
    .call(document.getElementsByTagName('head')[0].getElementsByTagName('link'))
    .filter(
      value => value.href.includes('css') && (value.href.indexOf('avue') > -1 || value.href.indexOf('element') > -1)
    )

  for (let i = 0; i < links.length; i++) {
    const link = links[i]
    const res = await getResource(link.href)
    const cssText = res.data.replace(/@font-face\s?\{[\s\S]*?}/, '')
    const newCssText = replaceColor(cssText, originalThemeCluster, newThemeCluster)
    let styleTag = document.getElementById(`${themeStylePrefix}${i}`)
    if (!styleTag) {
      styleTag = document.createElement('style')
      styleTag.id = `${themeStylePrefix}${i}`
      styleTag.innerText = newCssText
      link.after(styleTag)
    } else {
      styleTag.innerText = newCssText
    }
  }

  /*

  const originalCluster = getThemeCluster(oldVal.replace('#', ''))

  const styles = [].slice.call(document.querySelectorAll('style'))

  styles.forEach(style => {
    const { innerText } = style
    if (typeof innerText !== 'string') {
      return
    }
    style.innerText = replaceColor(innerText, originalCluster, newThemeCluster)
  }) */
}

export default {
  data() {
    return {
      chalk: '',
      themeVal: originalThemeColor
    }
  },
  created() {
    this.themeVal = this.themeColor
  },
  watch: {
    async themeVal(val, oldVal) {
      this.setThemeColor(val)
      await updateTheme(val, oldVal)
    }
  },
  computed: {
    ...mapState('viewState', ['themeColor'])
  },
  methods: {
    ...mapMutations('viewState', ['setThemeColor'])
  }
}
